home *** CD-ROM | disk | FTP | other *** search
/ Dr. Windows 3 / dr win3.zip / dr win3 / WINPROGS / MODEM2.ZIP / MODEM.CPP < prev    next >
C/C++ Source or Header  |  1993-10-11  |  16KB  |  571 lines

  1. /*
  2. This program is the simplest of simple serial communications apps.
  3. I wrote it to learn myself how to use a modem in windows.  I have had
  4. success using two copies of it to communicate across phone lines with
  5. one another.  For other serial devices, I doubt this program is Appropriate.
  6.  It is written under TC++ 3.0/win and should work under any Borland
  7. windows compiler in windows 3.1.  Be sure to include the resource file
  8. in the program, or create your own resources.
  9.  
  10.     An interesting note on functionality: Most of the demo programs
  11. I've seen advocate using the Idle() procedure in the TApplication object
  12. to process incoming information from the port.  However, from my own
  13. experience, THIS IS NOT THE WAY TO DO IT!  Instead, this program lets
  14. Windows send it messages telling it when to read the buffer etc...
  15.  
  16. Good luck, and email me at
  17.  
  18. jawhitti@midway.ecn.uoknor.edu
  19.  
  20. if you have any questions.  The program runs to near 600 lines, but is
  21. really quite simple.  Don't be intimidated!
  22. */
  23.  
  24.  
  25. #define STRICT
  26. #define WIN31
  27.  
  28. /* if you want to use the dynamic libraries, set memory model to large,
  29. and case-sensitive link to off, and leave _CLASSDLL defined.  Otherwise
  30. comment it out. */
  31.  
  32. #define _CLASSDLL
  33.  
  34. #include <owl.h>
  35. #include <edit.h>
  36. /* bwindow is not necessary, it just makes a gray window. The program
  37. works just the same if you derive TSerialWindow from TWindow. */
  38. #include <bwindow.h>
  39.  
  40. // #defines for the program. Change them to fit your resources,etc...
  41. #define CM_DIAL 101
  42. #define CM_HANGUP 102
  43. #define UM_ERROR WM_USER+1
  44. #define UM_DATA WM_USER+2
  45. // Size of buffer to recieve incoming text...
  46. #define MAXINPUTLENGTH 80
  47. // Size of Phone number buffer...
  48. #define PHONEINPUTLENGTH 25
  49.  
  50.  
  51. _CLASSDEF(TSerialApp)
  52. // TSerial app is just a TApplication that sets up a TSerialWindow
  53. class TSerialApp : public TApplication
  54. {
  55.   public:
  56.   TSerialApp(LPSTR Aname, HINSTANCE hInstance, HINSTANCE hPrevInstance,
  57.      LPSTR lpCmdLine, int nCmdShow)
  58.      : TApplication(Aname, hInstance, hPrevInstance, lpCmdLine, nCmdShow){};
  59.   virtual void InitMainWindow();
  60. };
  61.  
  62. _CLASSDEF(TSerialWindow)
  63. class TSerialWindow: public TBWindow
  64. {
  65. /* This class is the backbone of the program.  It likely is not the BEST
  66. way to do things, but it works.  I plan to modify it to make it more
  67. easily inherited.  Do as you please... */
  68.  
  69.     public:
  70. // Handle to Borland custom controls...
  71.         HANDLE BWCCMod;
  72.  
  73.         char PhoneNumber[PHONEINPUTLENGTH];
  74.         char Command[MAXINPUTLENGTH];
  75. //CPort holds the current open COM Port, y controls a primitive
  76. //Screen scroll.
  77.         int  CPort,y;
  78.         TSerialWindow(PTWindowsObject AParent, LPSTR ATitle);
  79.         virtual void SetupWindow();
  80.         virtual void CloseWindow();
  81.         virtual void CommEvent();
  82.         virtual void CheckReceiveBuffer();
  83.         virtual void DialPhone(RTMessage Msg)  = [CM_FIRST+ 101];
  84.         virtual void SendText(RTMessage Msg)   = [CM_FIRST+ 102];
  85.         virtual void GetStatus(RTMessage Msg)  = [CM_FIRST+ 103];
  86.         virtual void SendCommand(RTMessage Msg)= [CM_FIRST+ 104];
  87.         virtual void SerError(RTMessage Msg)  = [WM_FIRST+UM_ERROR];
  88.         virtual void SerData(RTMessage Msg)   = [WM_FIRST+UM_DATA];
  89.  
  90. //This procedure is important, and must be enabled in SetupWindow
  91. //with the ENABLECOMMNOTIFICATION call.
  92.         virtual int CommNotification(RTMessage Msg) = [WM_COMMNOTIFY];
  93.  };
  94.  
  95. //These dialog classes control some simple dialogs.  Play with them
  96. //to make the program more fun.
  97.  
  98. //Get user input.
  99. _CLASSDEF(TMyInputDialog)
  100. class TMyInputDialog : public TDialog
  101.     {
  102.     public : TMyInputDialog(PTWindowsObject AParent, LPSTR AResource);
  103.     };
  104.  
  105. //Get Phone number
  106. _CLASSDEF(TPhoneInputDialog)
  107. class TPhoneInputDialog : public TDialog
  108.     {
  109.     public : TPhoneInputDialog(PTWindowsObject AParent, LPSTR AResource);
  110.     };
  111.  
  112. //Select a COM port.  Default is COM2
  113. _CLASSDEF(TCommPortDialog)
  114. class TCommPortDialog : public TDialog
  115.     {
  116.     public : TCommPortDialog(PTWindowsObject AParent, LPSTR AResource);
  117.     private:
  118.     void PickOne(RTMessage Msg) =  [ID_FIRST + 101];
  119.     void PickTwo(RTMessage Msg) =  [ID_FIRST + 102];
  120.     void PickThree(RTMessage Msg)= [ID_FIRST + 103];
  121.     void PickFour(RTMessage Msg) = [ID_FIRST + 104];
  122.  
  123.     };
  124.  
  125.  
  126. void TSerialApp::InitMainWindow()
  127.     {
  128.     MainWindow = new TSerialWindow(NULL,Name);
  129.     }
  130.  
  131. //******************************************************
  132. // TSerialWindow member functions...                   *
  133. //******************************************************
  134.  
  135. TSerialWindow::TSerialWindow(PTWindowsObject AParent, LPSTR ATitle)
  136.     : TBWindow(AParent,ATitle)
  137. //Simple constructor does nothing special
  138.     {
  139.     PhoneNumber[0] = '\0';
  140.     CPort = -1; y=10;
  141.     AssignMenu("MENU_1");
  142.     BWCCMod=LoadLibrary("BWCC.DLL");
  143.     }
  144.  
  145. void TSerialWindow::SetupWindow()
  146.     {
  147.     int WhichPort;
  148.     DCB CommData;
  149.     LPSTR ACommPort;
  150.  
  151.     TBWindow::SetupWindow();
  152.     MessageBeep(MB_OK);
  153.     //Get the COM Port preference...
  154.     WhichPort=GetModule()->ExecDialog(new TCommPortDialog(this, "DIALOG_3"));
  155.     switch(WhichPort)
  156.         {
  157.         case 1: CPort = OpenComm("COM1", 1024, 1024); break;
  158.         case 3: CPort = OpenComm("COM3", 1024, 1024); break;
  159.         case 4: CPort = OpenComm("COM4", 1024, 1024); break;
  160.         default:CPort = OpenComm("COM2", 1024, 1024); break;
  161.         }
  162.    //OpenComm is <0 if the port fails to open...
  163.         if(CPort < 0)
  164.         {
  165.         MessageBeep(MB_ICONEXCLAMATION);
  166.         MessageBox(HWindow,"Comm port not open","Uh-Oh",MB_OK);
  167.         }
  168.     //Retrieve default Port settings...
  169.     GetCommState(CPort, &CommData);
  170.     //Adjust for app specific parameters....
  171.     CommData.BaudRate = 2400;
  172.     CommData.ByteSize = 8;
  173.     CommData.Parity = NOPARITY;
  174.     CommData.StopBits = ONESTOPBIT;
  175.     CommData.DsrTimeout =1000;
  176.     //Set the COM port to new parameters...
  177.     if(SetCommState(&CommData)!=0)
  178.         {
  179.         MessageBeep(MB_ICONEXCLAMATION);
  180.         MessageBox(HWindow,"Comm Port not configured","Error",MB_OK+MB_ICONEXCLAMATION);
  181.         }
  182.      //Flush Input and output buffers...
  183.      FlushComm(CPort,0); FlushComm(CPort,1);
  184.  
  185.      //Tell windows to send CommNotification messages to this window...
  186.      if (EnableCommNotification(CPort,HWindow,160,-1)==0)
  187.         {
  188.         MessageBeep(MB_ICONEXCLAMATION);
  189.         MessageBox(HWindow,"EnableCommNotification Failed","Error",MB_OK+MB_ICONEXCLAMATION);
  190.         }
  191.      //Tell windows to notify program of ANY comport message...
  192.      SetCommEventMask(CPort,0xFFFF);
  193.  
  194.      //Modem Initialization string.  Set to whatever...
  195.      WriteComm(CPort,"ATE1 S12=10\r",13);
  196.      }
  197.  
  198.  
  199. void TSerialWindow::CloseWindow()
  200.     {
  201.         CloseComm(CPort);
  202.         TBWindow::CloseWindow();
  203.     }
  204.  
  205. void TSerialWindow::CheckReceiveBuffer()
  206.  
  207. //This program looks in the recieve buffer and retrieves information
  208. //in it into Buffer.  If an error occurs, a UM_ERROR message is sent,
  209. //else a UM_DATA message is sent, with a pointer to the data in LParam.
  210.     {
  211.     int Ret,Err,i;
  212.     char Buffer[80];
  213.     COMSTAT Comstat;
  214.  
  215.     for(i=0;i<80;i++)Buffer[i]='\0';
  216.     if(CPort>=0)
  217.         {
  218.         Ret = ReadComm(CPort, Buffer, 80);
  219.         if(Ret<0)
  220.             {
  221.             Err = GetCommError(CPort, &Comstat);
  222.             if(Err>0)SendMessage(HWindow, UM_ERROR, 3, Err);
  223.             }
  224.         if(Ret>0)
  225.             {
  226.             SendMessage(HWindow, UM_DATA,Ret,(long)Buffer);
  227.             }
  228.          }
  229.     }
  230.  
  231. void TSerialWindow::CommEvent()
  232.     {
  233.     int event;
  234.     char Buffer[80];
  235.  
  236.     //Simple procedure Filters event messages.  For most, simply
  237.     //sends a message to itself to write on the sreen what the
  238.     //message was.  Events are coded it a bitfield, so each IF checks
  239.     //for a specific flag.  Several flags may be checked at once, so
  240.     //a SWITCH is not practical.
  241.     event = GetCommEventMask(CPort,0xFFFF);
  242.     if(event & EV_BREAK)
  243.         {
  244.         wsprintf(Buffer,"EV_BREAK");
  245.         SendMessage(HWindow,UM_DATA,lstrlen(Buffer),(long)Buffer);
  246.         }
  247.     if(event & EV_CTS)
  248.         {
  249.         wsprintf(Buffer,"EV_CTS");
  250.         SendMessage(HWindow,UM_DATA,lstrlen(Buffer),(long)Buffer);
  251.         }
  252.     if(event & EV_CTSS)
  253.         {
  254.         wsprintf(Buffer,"EV CTSS...");
  255.         PostMessage(HWindow,UM_DATA,lstrlen(Buffer),(long)Buffer);
  256.         }
  257.     if(event & EV_DSR)
  258.         {
  259.         wsprintf(Buffer,"EV_DSR");
  260.         SendMessage(HWindow,UM_DATA,lstrlen(Buffer),(long)Buffer);
  261.         }
  262.     if(event & EV_ERR)
  263.         {
  264.         wsprintf(Buffer,"EV_ERR");
  265.         SendMes